const defaultSceneOrPrefab = "./assets/scenes/main.yaml";
//const defaultSceneOrPrefab = "./assets/scenes/schoolgateScene.yaml";
//const defaultSceneOrPrefab = "./assets/scenes/schoolgateScene.yaml";
//const defaultSceneOrPrefab = "./assets/scenes/cookScene.yaml";
//const defaultSceneOrPrefab = "./assets/scenes/startGame.yaml";
//const defaultSceneOrPrefab = "./assets/scenes/changeDays.yaml";
//const defaultSceneOrPrefab = "./assets/prefabs/mainRole.yaml";
//const defaultSceneOrPrefab = "./assets/prefabs/testprefabs.yaml";
//const defaultSceneOrPrefab = "./assets/prefabs/animationEidtor.yaml";
//const defaultSceneOrPrefab = "./assets/scenes/zxwTestScene.yaml";
//const defaultSceneOrPrefab = "./assets/scenes/UI.yaml";

async function startupCompiler() {
  const { createServer } = require("vite");
  const server = await createServer({
    // 任何合法的用户配置选项，加上 `mode` 和 `configFile`
    configFile: false,
    root: __dirname,

    server: {
      port: 3000,
    },
  });
  await server.listen();

  server.printUrls();
}

let runtimeView;

async function startEditor() {
  const { app, BrowserWindow, BrowserView } = require("electron");

  function createWindow() {
    const editorProcess = new BrowserWindow({
      width: 1920,
      height: 1080,
      webPreferences: {
        nodeIntegration: true, //允许渲染进程使用Nodejs
        contextIsolation: false, //允许渲染进程使用Nodejs
      },
    });
    editorProcess.loadURL("http://localhost:3000/editor.html");
    editorProcess.openDevTools();

    setTimeout(() => {
      runtimeView = new BrowserView();
      editorProcess.setBrowserView(runtimeView);
      runtimeView.setBounds({ x: 250, y: 30, width: 960, height: 540 });
      const mode = "edit";
      runtimeView.webContents.loadURL(
        `http://localhost:3000/index.html?mode=${mode}&prefab=${encodeURIComponent(
          defaultSceneOrPrefab
        )}`
      );
      runtimeView.webContents.openDevTools({ mode: "undocked" });
    }, 5000);
  }

  app.whenReady().then(() => {
    createWindow();
    app.on("activate", () => {
      if (BrowserWindow.getAllWindows().length === 0) createRuntimeProcess();
    });
  });

  app.on("window-all-closed", () => {
    if (process.platform !== "darwin") app.quit();
  });
}

function generateAssetsYaml() {
  const fs = require("fs");
  const imageFiles = fs.readdirSync("assets/images");
  const imageAssets = imageFiles
    .filter((item) => item.includes(".jpg") || item.includes(".png"))
    .map((item) => "./assets/images/" + item);

  const animationFiles = fs.readdirSync("assets/animations");
  const animationImageAssets = animationFiles
    .filter((item) => item.includes(".jpg") || item.includes(".png"))
    .map((item) => "./assets/animations/" + item);
  const animationYamlAssets = animationFiles
    .filter((item) => item.includes(".yaml"))
    .map((item) => "./assets/animations/" + item);
    
    const prefabFiles = fs.readdirSync("assets/prefabs");
    const prefabAssets = prefabFiles
      .filter((item) => item.includes(".yaml"))
      .map((item) => "./assets/prefabs/" + item);

    const sceneFiles = fs.readdirSync("assets/scenes");
    const sceneAssets = sceneFiles
      .filter((item) => item.includes(".yaml"))
      .map((item) => "./assets/scenes/" + item);
    
    const soundFiles = fs.readdirSync("assets/sounds");
    const soundAssets = soundFiles
      .filter((item) => item.includes(".mp3") || item.includes(".m4a"))
      .map((item) => "./assets/sounds/" + item);
  
    const content =
      "images:\n" +
      imageAssets.map((item) => "  - " + item).join("\n") +
      "\n" +
      "prefabs:\n" +
      prefabAssets.map((item) => "  - " + item).join("\n")+
      "\n" +
      "animationImages:\n" +
      animationImageAssets.map((item) => "  - " + item).join("\n")+
      "\n" +
      "animationYamlAssets:\n" +
      animationYamlAssets.map((item) => "  - " + item).join("\n")+
      "\n" +
      "sceneAssets:\n" +
      sceneAssets.map((item) => "  - " + item).join("\n")+
      "\n" +
      "soundAssets:\n" +
      soundAssets.map((item) => "  - " + item).join("\n");
      fs.writeFileSync("./assets/assets.yaml", content, "utf-8");
}

async function startup() {
  generateAssetsYaml();
  new WebSocketProxy().start();
  await startupCompiler();
  await startEditor();
}

class WebSocketProxy {
  editorClient;
  runtimeClient;

  start() {
    const { Server } = require("ws");
    const wss = new Server({ port: 1234 });
    wss.on("connection", (client) => {
      client.on("message", (text) => {
        const message = JSON.parse(text);
        if (message.command === "login") {
          this.handleLogin(message, client);
        } else if (message.command === "changeMode") {
          this.handleChangeMode(message);
        } else {
          this.handleDispatchToOtherRendererProcess(message, text);
        }
      });
    });
  }

  handleChangeMode(message) {
    const mode = message.data;
    runtimeView.webContents.loadURL(
      `http://localhost:3000/index.html?mode=${mode}&prefab=${encodeURIComponent(
        defaultSceneOrPrefab
      )}`
    );
  }

  handleLogin(data, client) {
    if (data.id === "editor") {
      this.editorClient = client;
    } else if (data.id === "runtime") {
      this.runtimeClient = client;
    }
    if (this.editorClient && this.runtimeClient) {
      const text = JSON.stringify({ command: "loginSuccess" });
      this.editorClient.send(text);
      this.runtimeClient.send(text);
    }
  }

  handleDispatchToOtherRendererProcess(data, text) {
    if (data.id === "editor") {
      this.runtimeClient.send(text);
    } else if (data.id === "runtime") {
      this.editorClient.send(text);
    }
  }
}

startup().catch((e) => {
  console.log(e);
});
